package com.photoeditor.demo.ui.widget.image;

import android.content.Context;
import android.widget.Scroller;

/**
 * 这个类用于获取平滑的动画所需要的值
 */
public class AnimationHelper {

    private Scroller mScroller;

    private static final float DECELERATE_VALUE = 3.0f;

    public static final int SCALE_MAX = 100000;

    private int mMode = MODE_NONE;

    public static final int MODE_NONE = 0;

    public static final int MODE_SCROLL = 1;

    public static final int MODE_FLING = 2;

    public static final int MODE_SCALE = 3;

    public Point mPoint;

    public Point mLastPositionPoint;

    /**
     * x用于存储最终的直  y用于存储最终的scale
     */
    public Point mScalePoint;

    public AnimationHelper(Context context) {
        mScroller = new Scroller(context);
        mPoint = new Point();
        mLastPositionPoint = new Point();
        mScalePoint = new Point();
    }

    public void foreFinish() {
        mScroller.forceFinished(true);
        mMode = MODE_NONE;
    }

    public boolean isFinished() {
        return mScroller.isFinished();
    }

    public int getMode() {
        return mMode;
    }

    public void setMode(int mode) {
        mMode = mode;
    }

    /**
     * 调用这个方法记得处理最后一次的偏移  或者  缩放
     *
     * @return
     */
    public Point abortAnimation() {
        mScroller.abortAnimation();
        if (mMode == MODE_SCALE) {//返回当前的scaleX scaleY
            mPoint.x = mScalePoint.x;
            mPoint.y = mPoint.x;
            mMode = MODE_NONE;
            return mPoint;
        } else if (mMode == MODE_FLING || mMode == MODE_SCROLL) {//返回偏移的dx  dy
            mPoint.x = mScroller.getCurrX() - mLastPositionPoint.x;
            mPoint.y = mScroller.getCurrY() - mLastPositionPoint.y;
            mLastPositionPoint.x = mScroller.getCurrX();
            mLastPositionPoint.y = mScroller.getCurrY();
            mMode = MODE_NONE;
            return mPoint;
        } else {
            return null;
        }
    }

    public Point getNextValue() {
        if (mScroller.computeScrollOffset()) {
            if (mMode == MODE_SCALE) {//返回当前的scaleX scaleY
                int currx = mScroller.getCurrX();
                int finalX = mScroller.getFinalX();
                if (currx == finalX) {
                    mPoint.x = mScalePoint.x;
                    mPoint.y = mPoint.x;
                } else {
                    mPoint.x = (currx * 1.0f + mLastPositionPoint.x) / SCALE_MAX;
                    mPoint.y = mPoint.x;
                }
                return mPoint;
            } else if (mMode == MODE_FLING || mMode == MODE_SCROLL) {//返回偏移的dx  dy
                mPoint.x = mScroller.getCurrX() - mLastPositionPoint.x;
                mPoint.y = mScroller.getCurrY() - mLastPositionPoint.y;
                mLastPositionPoint.x = mScroller.getCurrX();
                mLastPositionPoint.y = mScroller.getCurrY();
                return mPoint;
            }
        }
        return null;
    }

    public void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY) {
        mMode = MODE_FLING;
        mLastPositionPoint.x = startX;
        mLastPositionPoint.y = startY;
        mScroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY);
    }

    /**
     * 进行了忽略计算 可能导致最后的缩放大小与实际的不等
     *
     * @param foucusX
     * @param foucusY
     * @param startScale
     * @param endScale
     */
    public void scale(float foucusX, float foucusY, float startScale, float endScale) {
        mMode = MODE_SCALE;
        mLastPositionPoint.x = Math.round(startScale * SCALE_MAX);
        mLastPositionPoint.y = 0;
        mPoint.foucusX = foucusX;
        mPoint.foucusY = foucusY;
        mScalePoint.x = endScale;
        mScalePoint.y = endScale;
        mScroller.startScroll(0, 0, Math.round((endScale - startScale) * SCALE_MAX), 0);
    }

    /**
     * 进行了忽略计算 可能导致最后的缩放大小与实际的不等
     *
     * @param foucusX
     * @param foucusY
     * @param startScale
     * @param endScale
     * @param duration
     */
    public void scale(float foucusX, float foucusY, float startScale, float endScale, int duration) {
        mMode = MODE_SCALE;
        mLastPositionPoint.x = Math.round(startScale * SCALE_MAX);
        mLastPositionPoint.y = 0;
        mPoint.foucusX = foucusX;
        mPoint.foucusY = foucusY;
        mScalePoint.x = endScale;
        mScalePoint.y = endScale;
        mScroller.startScroll(0, 0, Math.round((endScale - startScale) * SCALE_MAX), 0, duration);
    }

    public void scroll(int startX, int startY, int dx, int dy) {
        mMode = MODE_SCROLL;
        mScroller.startScroll(startX, startY, dx, dy);
        mLastPositionPoint.x = mScroller.getStartX();
        mLastPositionPoint.y = mScroller.getStartY();
    }

    public void scroll(int startX, int startY, int dx, int dy, int duration) {
        mMode = MODE_SCROLL;
        mScroller.startScroll(startX, startY, dx, dy, duration);
        mLastPositionPoint.x = mScroller.getStartX();
        mLastPositionPoint.y = mScroller.getStartY();
    }

    public class Point {
        float x;
        float y;
        float foucusX;
        float foucusY;

        public Point() {
        }

        public float getCurrentScaleX() {
            return x;
        }

        public float getCurrentScaleY() {
            return y;
        }

        public float getDx() {
            return x;
        }

        public float getDy() {
            return y;
        }

        public float getFoucusX() {
            return foucusX;
        }

        public float getFoucusY() {
            return foucusY;
        }
    }
}
